package cn.getech.data.development.service.impl;

import cn.getech.data.development.entity.*;
import cn.getech.data.development.mapper.*;
import cn.getech.data.development.model.dto.AlarmNotifyDto;
import cn.getech.data.development.model.dto.AlarmSaveDto;
import cn.getech.data.development.model.vo.AlarmSearchVO;
import cn.getech.data.development.model.vo.AlarmVO;
import cn.getech.data.development.service.AlarmObjectService;
import cn.getech.data.development.service.AlarmReceivedService;
import cn.getech.data.development.service.AlarmService;
import cn.getech.data.intelligence.common.exception.RRException;
import cn.getech.data.intelligence.common.utils.Constant;
import cn.getech.data.intelligence.common.utils.PageUtils;
import cn.getech.system.center.utils.ShiroUtils;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AlarmServiceImpl extends ServiceImpl<AlarmMapper, Alarm> implements AlarmService {

    @Resource
    private AlarmMapper alarmMapper;
    @Autowired
    private AlarmReceivedService alarmReceivedService;
    @Autowired
    private AlarmObjectService alarmObjectService;

    @Override
    public boolean saveOrUpdate(AlarmSaveDto alarmSaveDto) {
        Alarm alarm = new Alarm();
        BeanUtils.copyProperties(alarmSaveDto, alarm);
        int userId = ShiroUtils.getUserId().intValue();
        if (alarm.getId() == null) {
            alarm.setCreatePer(userId);
            alarm.setTenantId(ShiroUtils.getTenantId());
        }
        alarm.setFailStatus(alarmSaveDto.getFailStatus());
        alarm.setUpdatePer(userId);
        if (CollectionUtil.isNotEmpty(alarmSaveDto.getAlarmModes())) {
            alarm.setAlarmMode(Joiner.on(",").join(alarmSaveDto.getAlarmModes()));
        }
        // 修改的时候如果前端删除了免打扰时间，则把免打扰时间设为空
        if (alarm.getId() != null && alarm.getNoDisturbingStartTime() == null && alarm.getNoDisturbingEntTime() == null) {
            alarmMapper.updateNoDisturbingTimeNull(alarm.getId());
        }
        if(alarm.getId() != null){
            Alarm alarmOlder = alarmMapper.selectById(alarm.getId());
            if(alarmOlder == null){
                throw new RRException("编辑的报警信息不存在！");
            }
            alarm.setTenantId(alarmOlder.getTenantId());
        }
        if (super.saveOrUpdate(alarm)) {
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.eq("alarm_id", alarm.getId());
            alarmReceivedService.remove(wrapper);
            List<AlarmReceived> alarmReceivedList = alarmSaveDto.getReceivedList();
            if (CollectionUtil.isNotEmpty(alarmReceivedList)) {
                for (AlarmReceived item : alarmReceivedList) {
                    if (item.getId() == null) {
                        item.setCreatePer(userId);
                    }
                    item.setUpdatePer(userId);
                    item.setAlarmId(alarm.getId());
                    item.setAlarmType(Constant.AlarmTypeEnum.TASK_ALARM.getCode());
                }
                alarmReceivedService.saveOrUpdateBatch(alarmReceivedList);
            }
            if (CollectionUtil.isNotEmpty(alarmSaveDto.getAlarmObjects())) {
                alarmSaveDto.getAlarmObjects().stream().forEach(item -> {
                    item.setAlarmId(alarm.getId());
                    item.setObjectType(alarm.getObjectType());
                });
                alarmObjectService.remove(wrapper);
                alarmObjectService.saveOrUpdateBatch(alarmSaveDto.getAlarmObjects());
            }
            return true;
        }
        return false;
    }

    @Override
    public AlarmVO getInfoById(Integer id) {
        Alarm alarm = alarmMapper.selectById(id);
        if (alarm != null) {
            AlarmVO vo = new AlarmVO();
            BeanUtils.copyProperties(alarm, vo);
            if (alarm.getNoDisturbingStartTime() != null) {
                vo.setNoDisturbingStartTime(alarm.getNoDisturbingStartTime().substring(0, alarm.getNoDisturbingStartTime().length() - 2));
            }
            if (alarm.getNoDisturbingEntTime() != null) {
                vo.setNoDisturbingEntTime(alarm.getNoDisturbingEntTime().substring(0, alarm.getNoDisturbingEntTime().length() - 2));
            }
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.eq("alarm_type", Constant.AlarmTypeEnum.TASK_ALARM.getCode());
            wrapper.eq("alarm_id", id);
            List<AlarmReceived> receiveds = alarmReceivedService.list(wrapper);
            vo.setReceivedList(receiveds);
            wrapper = new QueryWrapper();
            wrapper.eq("alarm_id", id);
            List<AlarmObject> alarmObjects = alarmObjectService.list(wrapper);
            vo.setAlarmObjects(alarmObjects);
            return vo;
        }
        return null;
    }

    @Override
    public PageUtils alarmPage(AlarmSearchVO vo) {
        long current = StrUtil.isNotBlank(vo.getPage()) ? Long.parseLong(vo.getPage()) : 1;
        long offset = StrUtil.isNotBlank(vo.getLimit()) ? Long.parseLong(vo.getLimit()) : 10;
        Page<AlarmVO> page = new Page(current, offset);
        IPage<AlarmVO> infoIPage = page;
        if (StringUtil.isNotBlank(vo.getReceivedPer())) {
            String[] receivedPers = vo.getReceivedPer().split(",");
            Map<Integer, Integer> alarmMap = new HashMap<>();
            for (String receivedPer : receivedPers) {
                List<AlarmVO> alarmList = alarmMapper.alarmVoList(receivedPer);
                if (CollectionUtil.isNotEmpty(alarmList)) {
                    for (AlarmVO alarmVO : alarmList) {
                        int count = alarmMap.get(alarmVO.getId()) == null ? 0 : alarmMap.get(alarmVO.getId()).intValue();
                        count += 1;
                        alarmMap.put(alarmVO.getId(), count);
                    }
                }
            }
            List<Integer> alarmIds = new ArrayList<>();
            for (Map.Entry<Integer, Integer> entry : alarmMap.entrySet()) {
                if (entry.getValue() == receivedPers.length) {
                    alarmIds.add(entry.getKey());
                }
            }
            vo.setAlarmIds(alarmIds);
            vo.setReceivedPerList(null);
            vo.setReceivedPer(null);
        }
        vo.setTenantId(ShiroUtils.getTenantId());
        infoIPage = alarmMapper.alarmPage(page, vo);

        if (CollectionUtil.isNotEmpty(infoIPage.getRecords())) {
            Set<Integer> alarmIds = infoIPage.getRecords().stream().map(item -> item.getId()).collect(Collectors.toSet());
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.in("alarm_id", alarmIds);
            List<AlarmReceived> receiveds = alarmReceivedService.list(wrapper);
            Map<Integer, List<String>> receivedMap = new HashMap<>();
            List<String> receivedNameList;
            if (CollectionUtil.isNotEmpty(receiveds)) {
                for (AlarmReceived received : receiveds) {
                    receivedNameList = receivedMap.get(received.getAlarmId());
                    receivedNameList = receivedNameList == null ? new ArrayList<>() : receivedNameList;
                    receivedNameList.add(received.getReceivedName());
                    receivedMap.put(received.getAlarmId(), receivedNameList);
                }
            }

            List<AlarmObject> alarmObjects = alarmObjectService.list(wrapper);
            Map<Integer, List<String>> alarmObjectMap = new HashMap<>();
            List<String> objectNameList;
            if (CollectionUtil.isNotEmpty(alarmObjects)) {
                for (AlarmObject object : alarmObjects) {
                    objectNameList = alarmObjectMap.get(object.getAlarmId());
                    objectNameList = objectNameList == null ? new ArrayList<>() : objectNameList;
                    objectNameList.add(object.getObjectName());
                    alarmObjectMap.put(object.getAlarmId(), objectNameList);
                }
            }

            for (AlarmVO record : infoIPage.getRecords()) {
                receivedNameList = receivedMap.get(record.getId());
                if (CollectionUtil.isNotEmpty(receivedNameList)) {
                    record.setReceivedNames(String.join(",", receivedNameList));
                }
                objectNameList = alarmObjectMap.get(record.getId());
                if (CollectionUtil.isNotEmpty(objectNameList)) {
                    record.setAlarmObjectNames(String.join(",", objectNameList));
                }
            }
        }
        return new PageUtils(infoIPage);
    }

    @Override
    public List<AlarmNotifyDto> getAlarmNotifyUsers(List<Integer> alarmObjectIds) {
        return alarmMapper.getAlarmNotifyUsers(alarmObjectIds);
    }

    @Override
    public List<AlarmNotifyDto>  getRecriverList() {
        return alarmMapper.getRecriverList(ShiroUtils.getTenantId());
    }

    @Override
    public List<AlarmNotifyDto>  getCreaterList() {
        return alarmMapper.getCreaterList(ShiroUtils.getTenantId());
    }

    @Override
    public String getUsrNameById(BigInteger userId) {
        return alarmMapper.getUsrNameById(userId);
    }



}
